package mapper

import (
	"playbook/ginsvr/src/global"
	"playbook/ginsvr/src/orm"
	"playbook/ginsvr/src/source/gene"
	"playbook/ginsvr/src/utils/stringutil"
	"strings"
)

type MapperParam struct {
	AtomName string
	AtomId   string
	SqlType  string
}

// 生成自定义sql场景的Mapper类
func GnenerateSqlMapper(param MapperParam) error {
	paramMap := buildSqlVariableMap(param)
	//mapperPath := buildSqlMapperPath(param.AtomName)
	//template.WiteToFile("MapperSql.java", mapperPath, paramMap)
	gsd := orm.GetGeneSrcDefine("mapper")
	err := gene.GeneSrcByTpl("MapperSql", gsd.Srcpath, param.AtomName+"Mapper"+".java", paramMap)
	return err
}

func buildSqlVariableMap(param MapperParam) map[string]string {
	var paramMap map[string]string = make(map[string]string)
	paramMap["packageName"] = buildPackageName("mapper")

	atomSvrDefine := orm.GetAtomSvrDefbyId(param.AtomId)
	paramRelationOut, _ := orm.GetParameterbyId(atomSvrDefine.Outputparamid, "")
	outSubParam := orm.GetParamById(paramRelationOut[0].Subparamid)
	inParam := orm.GetParamById(atomSvrDefine.Inputparamid)
	var outSubParam2 orm.Parameter
	if "List" == outSubParam.Classpath {
		paramRelationOut2, _ := orm.GetParameterbyId(outSubParam.Parameterid, "")
		outSubParam2 = orm.GetParamById(paramRelationOut2[0].Subparamid)
	}

	paramMap["inputParam"] = inParam.Classpath

	if "SELECT" != param.SqlType {
		paramMap["outputParam"] = ""
	} else {
		if "List" == outSubParam.Classpath {
			paramMap["outputParam"] = "import " + outSubParam2.Classpath + ";"
		} else {
			paramMap["outputParam"] = "import " + outSubParam.Classpath + ";"
		}
	}

	if "List" == outSubParam.Classpath {
		paramMap["list"] = "import java.util.List;"
	} else {
		paramMap["list"] = ""
	}

	paramMap["mapperName"] = param.AtomName + "Mapper"

	resultType := "int"
	if "SELECT" == param.SqlType {
		resultType = getRespType(outSubParam, outSubParam2, outSubParam.Classpath)
	}
	methodName := strings.ToLower(param.SqlType)
	inParamName := subName(inParam.Classpath)
	paramMap["methodInfo"] = resultType + " " + methodName + "(" + inParamName + " param" + ")"

	return paramMap
}

func subName(fullName string) string {
	return fullName[strings.LastIndex(fullName, ".")+1:]
}

func getRespType(param1 orm.Parameter, param2 orm.Parameter, classPath string) string {
	if "List" == classPath {
		return "List<" + subName(param2.Classpath) + ">"
	}
	return subName(param1.Classpath)
}

func buildSqlMapperPath(atomName string) string {
	localPath := orm.GetLocalPath(global.USER)
	gsd := orm.GetGeneSrcDefine("mapper")
	var sb strings.Builder
	sb.WriteString(localPath.LocalPath)
	sb.WriteString("\\")
	sb.WriteString(gsd.Srcpath)
	sb.WriteString("\\")
	sb.WriteString(atomName + "Mapper")
	sb.WriteString(".java")
	return sb.String()
}

// 单表场景生成Mapper类
func GenerateMapper(tableName string) error {
	// 封装变量
	paramMap := buildVariableMap(tableName)
	// 获取Mapper写出路径
	//mapperPath := buildMapperPath(tableName)
	// 按照模板写出
	//template.WiteToFile("Mapper.java", mapperPath, paramMap)

	gsd := orm.GetGeneSrcDefine("mapper")
	err := gene.GeneSrcByTpl("Mapper", gsd.Srcpath, buildMapperName(tableName)+".java", paramMap)
	return err
}

func buildVariableMap(tableName string) map[string]string {
	var paramMap map[string]string = make(map[string]string)
	modelName := buildModelName(tableName)
	paramMap["packageName"] = buildPackageName("mapper")
	paramMap["model"] = buildPackageName("model") + "." + modelName
	paramMap["mapperName"] = buildMapperName(tableName)
	paramMap["modelName"] = modelName

	return paramMap
}

func buildMapperPath(tableName string) string {
	localPath := orm.GetLocalPath("00001")
	gsd := orm.GetGeneSrcDefine("mapper")
	var sb strings.Builder
	sb.WriteString(localPath.LocalPath)
	sb.WriteString("\\")
	sb.WriteString(gsd.Srcpath)
	sb.WriteString("\\")
	sb.WriteString(buildMapperName(tableName))
	sb.WriteString(".java")
	return sb.String()
}

func buildMapperName(tableName string) string {
	var modelName string
	for _, c := range strings.Split(tableName, "_") {
		modelName = modelName + strings.ToUpper(c[:1]) + c[1:]
	}
	return modelName + "Mapper"
}

func buildModelName(tableName string) string {
	var expresionArr = strings.Split(tableName, "_")
	var sb strings.Builder
	for i := 0; i < len(expresionArr); i++ {
		sb.WriteString(stringutil.GetTitleStr(expresionArr[i]))
	}
	sb.WriteString("Model")
	return sb.String()
}

func buildPackageName(keyType string) string {
	gsd := orm.GetGeneSrcDefine(keyType)
	var srcPath = gsd.Srcpath
	var packageName = srcPath[strings.Index(srcPath, "java")+5:]
	packageName = strings.ReplaceAll(packageName, "\\", ".")
	return packageName
}
